﻿using System;

using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;

namespace FileExplorer
{
    public static class FileIconUtil
    {
        public static Icon GetIconFromPath(string path)
        {
            SHFILEINFO info = new SHFILEINFO();

            IntPtr hSmallImage = SHGetFileInfo(path, 0, ref info, (uint)Marshal.SizeOf(info), SHGFI_ICON | SHGFI_SMALLICON);
            if (info.hIcon == IntPtr.Zero) return null;
            Icon icon;
            lock (IconCache)
            {
                if (IconCache.TryGetValue(info.iIcon, out icon)) return icon;
                icon = Icon.FromHandle(info.hIcon);
                DestroyIcon(info.hIcon);
                IconCache.Add(info.iIcon, icon);
            }
            return icon;
        }

        private static Dictionary<uint, Icon> IconCache = new Dictionary<uint, Icon>();

        private const uint SHGFI_ICON = 0x100;
        private const uint SHGFI_SMALLICON = 0x1;
        private const uint SHGFI_LARGEICON = 0x0;

        [StructLayout(LayoutKind.Sequential)]
        internal struct SHFILEINFO
        {
            public IntPtr hIcon;
            public uint iIcon;
            public uint dwAttributes;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;

        };

        public static string ToFileSize(long size)
        {
            if (size <= 1000) return string.Format("{0} B", size);
            if (size < 100000) return string.Format("{0:F} kB", (float)(((size + 500F) / 1000F)));
            return string.Format("{0:F} MB", (float)(((size + 500F) / 1000000F)));
        }

        // The signature of SHGetFileInfo (located in Shell32.dll)

        [DllImport("coredll.dll")]
        private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);

        [DllImport("coredll.dll")]
        private static extern bool DestroyIcon(IntPtr hicon);
    }



}
